package com.fanrui.code.chess;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import com.fanrui.code.message.PlayerSession;
import com.fanrui.code.message.PlayerSessions;
import com.fanrui.code.player.ChessPlayerInfo;
import com.google.gson.annotations.Expose;
import com.google.protobuf.MessageLite;

public abstract class AbstractChessGamer<CARD extends IChessCard> implements IChessGamer<CARD> {
	
	/**
	 * gamerID
	 */
	private final int ID;
	
	/**
	 * 玩家ID
	 */
	@Expose
	private long playerID;
	
	/**
	 * 所在牌桌ID
	 */
	protected int tableID;
	
	/**
	 * 是否准备
	 */
	protected AtomicBoolean isReady = new AtomicBoolean(false);
	
	/**
	 * 手牌
	 */
	@Expose
	protected List<CARD> handCards = new ArrayList<CARD>();
	
	/**
	 * 分数
	 */
	protected AtomicLong income = new AtomicLong(0);
	
	/**
	 * 是否托管
	 */
	protected AtomicBoolean hosting = new AtomicBoolean(false);
	
	/**
	 * 暂离
	 */
	protected AtomicBoolean AFK = new AtomicBoolean(false);
	
	/**
	 * 是否已经离开
	 */
	protected AtomicBoolean leave = new AtomicBoolean(false);
	
	/**
	 * 等待操作时间
	 */
	protected AtomicInteger waitTime = null;
	
	@Expose
	protected ChessPlayerInfo playerInfo;
	
	protected String ip;
	
	protected double x;
	
	protected double y;
	
	public AbstractChessGamer(int ID, long playerID, int tableID, String ip, double x, double y) {
		this.ID = ID;
		this.playerID = playerID;
		this.tableID = tableID;
		playerInfo = new ChessPlayerInfo(playerID);
		this.ip = ip;
		this.x = x;
		this.y = y;
	}

	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public double getX() {
		return x;
	}

	public void setX(double x) {
		this.x = x;
	}

	public double getY() {
		return y;
	}

	public void setY(double y) {
		this.y = y;
	}

	@Override
	public long getPlayerID() {
		return playerID;
	}

	@Override
	public void send(MessageLite push) {
		PlayerSession session = PlayerSessions.getPlayerSession(playerID);
		if (session != null) {
			session.send(push);
		}
	}

	@Override
	public int getGamerID() {
		return ID;
	}

	@Override
	public int getTableID() {
		return tableID;
	}

	@Override
	public boolean isReady() {
		return isReady.get();
	}

	@Override
	public void setIsReady(boolean isReady) {
		this.isReady.set(isReady);
	}

	@Override
	public void addCard(Collection<CARD> cards) {
		handCards.addAll(cards);
	}

	@Override
	public void addCard(CARD card) {
		handCards.add(card);
	}
	
	/**  
	*  获取收益
	*  @return    
	*  long    
	*/  
	public long getIncome(){
		return income.get();
	}
	
	public void clearIncome(){
		income.set(0l);
	}
	
	public boolean getHosting() {
		return hosting.get();
	}

	public void setHosting(boolean hosting) {
		this.hosting.set(hosting);
		ITable table = ChessTableManager.getInstance().findByID(getTableID());
		if(table != null){
//			NotifyHost.Builder notify = NotifyHost.newBuilder();
//			notify.setIsHost(getHosting());
//			notify.setUserID(getPlayerID());
//			table.broadcast(notify.build());
		}
	}

	public boolean getAFK() {
		return AFK.get();
	}

	public void setAFK(boolean aFK) {
		this.AFK.set(aFK);
	}

	public boolean getLeave() {
		return leave.get();
	}

	public void setLeave(boolean leave) {
		this.leave.set(leave);
	}

	public int getWaitTime() {
		if(waitTime == null){
			return 0;
		}else{
			return waitTime.get();
		}
	
	}

	public void setWaitTime(AtomicInteger waitTime) {
		this.waitTime = waitTime;
	}
	
	public void setWaitTime(int waitTime) {
		if(this.waitTime != null){
			this.waitTime.set(waitTime);
		}
	}

	public List<CARD> getHandCards() {
		return handCards;
	}
	
	public ChessPlayerInfo getPlayerInfo() {
		return playerInfo;
	}

	public abstract MessageLite toCmd();
	
	public abstract MessageLite toCmd(long playerId);
	
	public abstract boolean addIncome(int val);

}
